﻿using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Bson.Serialization.Serializers;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities.ProductInvolvement;
using Sustainalytics.Entities.SustainableProducts;

namespace Sustainalytics.DataLayer.PI
{
    public class ProductInvolvementFrameworkRepository : RepositoryCollection<ProductInvolvementFramework>, IProductInvolvementFrameworkRepository
    {
        public ProductInvolvementFrameworkRepository(string url)
            :base(url)
        {
            if (!BsonClassMap<PIRange>.IsClassMapRegistered(typeof (PIRange)))
            {
                BsonClassMap.RegisterClassMap<PIRange>(a => a.AutoMap());
            }
            var map = BsonClassMap<PIRange>.LookupClassMap(typeof (PIRange));

            if (!BsonClassMap<SustainableProductsCategory>.IsClassMapRegistered(typeof(SustainableProductsCategory)))
            {
                var dic = new DictionaryInterfaceImplementerSerializer<Dictionary<int, PIRange>>(DictionaryRepresentation.ArrayOfArrays);
                var dic2=dic.WithValueSerializer(new BsonClassMapSerializer<PIRange>(map));
                BsonClassMap.RegisterClassMap<SustainableProductsCategory>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.RevenueRange).SetSerializer(dic2);

                });
            }
        }

        public virtual IList<ProductInvolvementFramework> ReadIndicators()
        {
            return ReadAll(null, null, null, Ordering<ProductInvolvementFramework>.Ascending(x=>x.Name));
        }

        public ProductInvolvementFramework ReadBySymbol(string symbol)
        {
            if (ReadAllWhere(pi => pi.Symbol == symbol).SingleOrDefault() == null)
                throw new ArgumentNullException();
            return ReadAllWhere(c => c.Symbol == symbol).Single();
        }
        public ProductInvolvementFramework ReadById(Guid id)
        {
            throw new NotImplementedException();
        }

        public void Create(IEnumerable<ProductInvolvementFramework> indicators)
        {
            foreach (var i in indicators)
                base.Create(i);
        }

        public void Update(IEnumerable<ProductInvolvementFramework> indicators)
        {
            foreach (var i in indicators)
                base.Update(i.Id, i);
        }

        public IList<ProductInvolvementCategory> GetIndicatorCategories(string piSymbol)
        {
            if (ReadAllWhere(pi => pi.Symbol == piSymbol).SingleOrDefault() == null)
                throw new ArgumentNullException();
            return ReadAllWhere(c => c.Symbol == piSymbol).Single().Categories;
        }
    }
}
